import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)

/**
 * The main actor in the world. This is the entity the user will know as him, and everything that happens 
 * in the world is about the Player.
 * 
 * @author Manuel Nava
 * @version 1.0
 */
public class Player extends Actor
{
   
    private int velY;
    private boolean jump;
    private int contVelY;
    private int contAttack;
    private int contImage;
    private boolean faceRight;
    private int timePowerUp;
    private int powerUp;
    private int contPowerUp;
    private int Life;
    private boolean attackSword;
    private Sword sword;
    
    /**
     * Constructor of the class player, set the initial values to their variables, booleans to zero and 
     * integers to false.
     */
    public Player()
    {
        velY=0;
        jump=false;
        contAttack=0;
        contImage=0;
        faceRight=true;
        contPowerUp=0;
        powerUp=0;
    }
    
    /**
     * The method act in this class check several flags and if the actor isn touching another actor, 
     * depending of the class it is touching it calls diferent methods or changes his image. Also checks 
     * the structur is touching to halt the act method and call another one of other class.
     */
    public void act() 
    {
        if(attackSword==true)
        {
            getWorld().removeObject(sword);
            attackSword=false;
        }
        if(isTouching(Enemy.class)||isTouching(Trap.class))
        {
           setImage(new GreenfootImage("lost.png"));
           Greenfoot.playSound("death.mp3");
           Greenfoot.delay(50); 
           lostLife();
           return;
        }
        if(isTouching(Tina.class))
        {
            getWorld().removeObject(getOneIntersectingObject(Tina.class));
            setImage(new GreenfootImage("andTina.png"));
            Greenfoot.delay(100);
            ((CaveWorld)(getWorld())).win();
            return;
        }
        
        if(((CaveWorld)(getWorld())).getLevel()==1)
           if(isTouching(Grass.class))
              {
                  ((CaveWorld)(getWorld())).finishLevel1();
                  return;
                }
        if(((CaveWorld)(getWorld())).getLevel()==2)
           if(isTouching(Cave.class)&&getOneIntersectingObject(Cave.class).getX()<340)
              {
                  ((CaveWorld)(getWorld())).finishLevel2();
                  return;
                }
        if(Greenfoot.isKeyDown("a")&&jump==false&&contVelY==0)
        {
           jump=true;
           setLocation(getX(),getY()-10);
           setImage(new GreenfootImage("jump-up.png"));
            if(!faceRight) getImage().mirrorHorizontally();
            Greenfoot.playSound("salto.mp3");
        }
        
        if(Greenfoot.isKeyDown("left")||Greenfoot.isKeyDown("right"))
           move();
        else if(Greenfoot.isKeyDown("s")&&contPowerUp==0)
           attack();
        else if(velY==0&&isTouching(Structure.class))
        {
            setImage(new GreenfootImage("stand.png"));
             if(!faceRight) getImage().mirrorHorizontally();
        }
        if(jump==true)
           jumping();
        if(contPowerUp!=0)
           contPowerUp--;
        if(timePowerUp!=0)
           timePowerUp--;
        gravity();
        setLocation(getX(),getY()+velY);
    }  
    
    /**
     * It calls the method losLife of the class CaveWorld.
     */
    public void lostLife()
    {
       ((CaveWorld)(getWorld())).lostLife();
    }
    
    /**
     * Sets values to the jump act of the player.
     */
    public void jumping()
    {
        if(contVelY==30||!Greenfoot.isKeyDown("a"))
        {
            jump=false;
            setImage(new GreenfootImage("jump-down.png"));
             if(!faceRight) getImage().mirrorHorizontally();
        }
        if(contVelY<30&&Greenfoot.isKeyDown("a"))
        {
            velY=-5;
            contVelY=contVelY+1;
        }
    }
    
    /**
     * Changes the movement of the actor to simulate the gravity of a planet. And moves the actor down 
     * until it is touching a Structure class object.
     */
    public void gravity()
    {
       if(this.isTouching(Structure.class))
       {
           if(this.isTouching(Ground.class))
           {
               velY=0;
               contVelY=0;
           }else 
           {
               Cloud cloud=(Cloud)(getOneIntersectingObject(Cloud.class));
               if(this.getY()>=(cloud.getY()-65)&&this.getY()<=cloud.getY()-60)
               {
                   velY=0;
                   contVelY=0;
                }
            }
        }
       else if(jump==false)
       {
            velY=5;
        }
    }
    
    /**
     * Changes the boolean variable faceRight depending of the key pushed and calls the method
     * changeImageMove.
     */
    public void move()
    {
        if(Greenfoot.isKeyDown("left"))
        {
            faceRight=false;
            if(velY==0)changeImageMove();
        }
        
        if(Greenfoot.isKeyDown("right"))
        {
            faceRight=true;
            if(velY==0)changeImageMove();
        }
       
    }
    
    /**
     * Changes the image the actor will have as long it moves along the scroll.
     */
    public void changeImageMove()
    {   
        if(contImage==9) contImage=0;
       if(!jump)
         switch(contImage)
         {
           case 0:setImage(new GreenfootImage("walk1.png"));
                  if(!faceRight) getImage().mirrorHorizontally();
                  contImage++;
                  break;
           case 3:setImage(new GreenfootImage("walk2.png"));
                  if(!faceRight) getImage().mirrorHorizontally();
                  contImage++;
                  break;
           case 6:setImage(new GreenfootImage("walk3.png"));
                  if(!faceRight) getImage().mirrorHorizontally();
                  contImage++;
                  break;
           default:contImage++;
                  break;
         }
    }
   
    /**
     * Setter for the powerUp variable.
     */
    public void setPowerUp(int d)
    {
        powerUp=d;
        if(d==2)
           timePowerUp=400;
        ((CaveWorld)(getWorld())).getSquare().setImage(d);
    }
    
    /**
     * Getter for the powerUp variable.
     */
    public int getPowerUp()
    {
        return powerUp;
    }
    
    /**
     * Change the image of the actor as long it throws an attack and add a object to the world depending
     * ont the powerUp vatiable. Also uses a counter to put a time space between attacks.
     */
    public void attack()
    {
        if(timePowerUp==0&&powerUp==2)
        {
            powerUp=0;
            ((CaveWorld)(getWorld())).getSquare().setImage(0);
        }
        if(powerUp==2)
        {
            setImage(new GreenfootImage("attack-sword.png"));
            if(faceRight) getWorld().addObject(sword=new Sword(),getX()+50,getY());
            if(!faceRight)
            {
                getImage().mirrorHorizontally();
                getWorld().addObject(sword=new Sword(),getX()-50,getY());
                sword.getImage().mirrorHorizontally();
            }
            attackSword=true;
            return;
        }
        setImage(new GreenfootImage("attack-fist.png"));
        if(!faceRight) getImage().mirrorHorizontally();
        if(powerUp==1)
            if(faceRight)getWorld().addObject(new Axe(true),getX()+50,getY());
            else  getWorld().addObject(new Axe(false),getX()-50,getY());
        contPowerUp=20;
        Greenfoot.delay(3);
        setImage(new GreenfootImage("stand.png"));
        if(!faceRight) getImage().mirrorHorizontally();
    }
    
    
}
